Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

кроссбарузерная подгрузка HTML+JS (HaZ)
Author Message
HaZ
Участник форума



Joined: 12 Jan 2008
Posts: 21
Карма: -1
   поощрить/наказать


PostPosted: Sat Jan 12, 2008 8:01 pm (написано за 5 минут 46 секунд)
   Post subject: кроссбарузерная подгрузка HTML+JS
Reply with quote

Пишу игровой сайт с использование XMLHttpRequest
При создании интерактивной карты мира возникла необходимость подгружать переменные и функции ява скрипта, причем переменные формируются на основе данных БД и по сути я обращаюсь к php-файлу, который генерирует нужные переменные (вида var естественно), функции и если нужно HTML

Первыми попытками было использование eval(), но как оказалось - таким макаром подружаются функции но никак не переменные
Для ИЕ нашел выход с использование window.execScript вместо eval, но аналогов такого замечательного метода для других браузеров я не нашел
В частности ищу решение для Оперы и Фокса. А есть ли такое решение ?
Back to top
View user's profile Send private message
Валенок
Участник форума



Joined: 06 Apr 2006
Posts: 520
Карма: -3
   поощрить/наказать


PostPosted: Sat Jan 12, 2008 8:10 pm (спустя 8 минут; написано за 2 минуты 16 секунд)
   Post subject:
Reply with quote

HaZ
Quote:
таким макаром подружаются функции но никак не переменные
просто выдавайте вашем пхпшником что-то вида
Code (JavaScript): скопировать код в буфер обмена
{
        var1: 'zn1',
        var2: 123,
        var3: [1,2,3],
        var4: new Array('aaa', 'bbb')
// ...
}
(через ru2.php.net/manual/ru/function.json-encode.php легче всего)
а потом, получая, делайте так:
Code (JavaScript): скопировать код в буфер обмена
 
тогда answer_vars.var1 будет 'zn1' и т.д.
Back to top
View user's profile Send private message
HaZ
Участник форума



Joined: 12 Jan 2008
Posts: 21
Карма: -1
   поощрить/наказать


PostPosted: Sat Jan 12, 2008 9:50 pm (спустя 1 час 40 минут; написано за 2 минуты 49 секунд)
   Post subject:
Reply with quote

немного уточню
мне надо чтобы подгружаемая переменная заменяла уже существующую
т.е. в исходном файле была обьявлена переменная скажем var vr1;
и подгружаю я переменную точно с таким же именем - она заменяет старую

Вашим метом погружается переменная answer_vars.vr1
можно как нибудь напрямую подгружать ?

скажем если написать не answer_vars = eval( от того что вы получили );
а просто eval( от того что вы получили );
это приемлемо ? наскоро сделал - не работает
Back to top
View user's profile Send private message
HaZ
Участник форума



Joined: 12 Jan 2008
Posts: 21
Карма: -1
   поощрить/наказать


PostPosted: Sat Jan 12, 2008 10:11 pm (спустя 20 минут; написано за 1 минуту 5 секунд)
   Post subject:
Reply with quote

кроме того судя по описанию так можно возвращать только переменные (вовзращается то массив)
т.е. без функций и уже тем более без хтмл
Back to top
View user's profile Send private message
Валенок
Участник форума



Joined: 06 Apr 2006
Posts: 520
Карма: -3
   поощрить/наказать


PostPosted: Sat Jan 12, 2008 11:51 pm (спустя 1 час 39 минут; написано за 2 минуты 51 секунду)
   Post subject:
Reply with quote

HaZ это не сработает, потому что область видимости будет другая
попробуйте вместо var my_var1 = 123; ставить то ли window.my_var1 = 123; то ли document.my_var1 = 123; (я не помню, куда деваются переменные, обьявленные чере "глобальный" var)

я имею в виду, что когда вы пишете (не внутри функции) var var_name = smth; , внутри обьекта window (или document) создается переменная (свойство) под названием var_name, и плясать надо от этого ^^ т.е. window выступает в роли глобального объекта
Back to top
View user's profile Send private message
An6rey
Участник форума



Joined: 30 Aug 2007
Posts: 69
Карма: 3
   поощрить/наказать


PostPosted: Sun Jan 13, 2008 2:03 am (спустя 2 часа 12 минут; написано за 14 минут 32 секунды)
   Post subject: Re: кроссбарузерная подгрузка HTML+JS
Reply with quote

HaZ wrote:
Первыми попытками было использование eval(), но как оказалось - таким макаром подружаются функции но никак не переменные
Для ИЕ нашел выход с использование window.execScript вместо eval, но аналогов такого замечательного метода для других браузеров я не нашел
В частности ищу решение для Оперы и Фокса. А есть ли такое решение ?
Неизвестно как Вы конкретно загружаете, что функции у Вас подгружаются. Так как область вилимости функций и переменных защищенных var одинаковая.

Конкретно по сабжу.

1. В не-IE браузерах вместо execScript() можно использовать window.eval(). От execScript отличается тем, что возвращает значение последнего выполненног оператора. (window.eval() != eval())

2. Можно использовать и просто eval() и не защищать переменые ключевым словом var.

Но по гамбургскому счету делать так нельзя (использовать глобальные переменные).Вы можете создать в глобальном пространстве "объект пространства имен".
То есть

var aaa={}
aaa.bbb={}

и сохранять все ваши загружаемые переменные как свойства глобального объекта

aaa.bbb.var1...
Back to top
View user's profile Send private message
HaZ
Участник форума



Joined: 12 Jan 2008
Posts: 21
Карма: -1
   поощрить/наказать


PostPosted: Sun Jan 13, 2008 10:33 am (спустя 8 часов 29 минут; написано за 6 минут 8 секунд)
   Post subject:
Reply with quote

An6rey
Огромное спасибо. window.eval() и вправду решил ситуацию, выступив аналогом window.execScript(). Проверил пока только на опере, но тем не менее уже шаг вперед.

Остальные способы предложенные An6rey и Валенок испытать так и не пришлось. Честно говоря они мне кажутся менее удобными.
Для кроссбраузерности сейчас только и остается ввести проверку на тип браузера и в зависимости от этого применять нужный метод.

P.s. А все таки - чем window.eval() отличается от eval ( к примеру: насколько я помню window.open() и open() индеинтичны )
Back to top
View user's profile Send private message
dimagolov
Участник форума



Joined: 04 Feb 2007
Posts: 1664
Карма: 96
   поощрить/наказать

Location: Christ Church, Barbados

PostPosted: Sun Jan 13, 2008 7:03 pm (спустя 8 часов 30 минут; написано за 1 минуту 18 секунд)
   Post subject:
Reply with quote

HaZ, window.eval() отличается от eval namespace-ом выполнения. то есть первый выполняет строку в контексте window, а второй - в текущем, то есть в this
Back to top
View user's profile Send private message
AKS
Участник форума



Joined: 28 Dec 2005
Posts: 1174
Карма: 102
   поощрить/наказать


PostPosted: Sun Jan 13, 2008 7:57 pm (спустя 53 минуты; написано за 2 минуты 8 секунд)
   Post subject:
Reply with quote

dimagolov wrote:
то есть первый выполняет строку в контексте window, а второй - в текущем, то есть в this
Не так все просто:
Code (JavaScript): скопировать код в буфер обмена
var s = 'this.f = null;';

var o = {
    f: function () {
        window.eval(s);
    }
};

o.f();

alert(o.f); // -> null (with SpiderMonkey)
 
Вообще, глобальная функция eval (метод объекта Global) не должна вызываться, как метод какого-либо объекта: Object:eval (Deprecated) (developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Object:eval).
Back to top
View user's profile Send private message Send e-mail
dimagolov
Участник форума



Joined: 04 Feb 2007
Posts: 1664
Карма: 96
   поощрить/наказать

Location: Christ Church, Barbados

PostPosted: Sun Jan 13, 2008 11:58 pm (спустя 4 часа 21 секунду; написано за 2 минуты 25 секунд)
   Post subject:
Reply with quote

AKS, Ваш пример ничуть не опровергает моего утверждения. Просто контекст в Вашем примере напрямую задан. Если бы он задан не был (а у HaZ именно так на 99%), то выходило бы то, что я написал. Или я в чем-то заблуждаюсь?
Back to top
View user's profile Send private message
AKS
Участник форума



Joined: 28 Dec 2005
Posts: 1174
Карма: 102
   поощрить/наказать


PostPosted: Mon Jan 14, 2008 7:45 am (спустя 7 часов 47 минут; написано за 2 минуты 12 секунд)
   Post subject:
Reply with quote

dimagolov wrote:
Или я в чем-то заблуждаюсь?
Я не хочу сказать, что Вы заблуждаетесь. Более того, я так понимаю, что мы все видим то, как работают движки, как сквозь тонированное стекло.
dimagolov wrote:
у HaZ именно так на 99%
Мне без разницы, как там у него. Я ведь пишу о том, как вообще работает eval. А работает он по-разному. Цель моего сообщения – выяснить есть ли еще какие-либо "отклонения" (может они кому-то известны).
Если верить Brendan Eich’у (bugzilla.mozilla.org/show_bug.cgi?id=352045#c1), то они с коллегами из Opera решили оставить вызов eval, как метод объекта window, но кроме этого в FF eval может быть вызван еще и как метод любого другого объекта:
Code (JavaScript): скопировать код в буфер обмена
var o = { a: 'test' };

alert(o.eval('a')); // -> 'test' (with SpiderMonkey)
 
Все это в FF работает с бог знает каких стародавних времен – видимо отсюда и непредсказуемость.
dimagolov wrote:
Ваш пример ничуть не опровергает моего утверждения.
Я ведь не опровергал, я написал: "Не так все просто...". К примеру, я видел такие сценарии, где изначально определяется ссылка на глобальный контекст:
Code (JavaScript): скопировать код в буфер обмена
var s = 'var global = this;';
Мой пример всего-навсего показывает, что такой сценарий может быть "сломан" eval’ом в FF.
Back to top
View user's profile Send private message Send e-mail
An6rey
Участник форума



Joined: 30 Aug 2007
Posts: 69
Карма: 3
   поощрить/наказать


PostPosted: Mon Jan 14, 2008 8:17 pm (спустя 12 часов 31 минуту; написано за 3 минуты 27 секунд)
   Post subject:
Reply with quote

Я скорее склонен трактовать такое поведение не как аномалию в window.eval(), а как аномалию this.
После входа в тело функции (метода), вызванного через объект (экземпляр) - this приписывается к глобальному контексту и window.eval() не меняет this с текущего объекта на window - хотя это только предположение.
Back to top
View user's profile Send private message
AKS
Участник форума



Joined: 28 Dec 2005
Posts: 1174
Карма: 102
   поощрить/наказать


PostPosted: Tue Jan 15, 2008 11:10 am (спустя 14 часов 52 минуты; написано за 1 минуту 38 секунд)
   Post subject:
Reply with quote

An6rey wrote:
Я скорее склонен трактовать такое поведение не как аномалию в window.eval(), а как аномалию this.
После входа в тело функции (метода), вызванного через объект (экземпляр) - this приписывается к глобальному контексту и window.eval() не меняет this с текущего объекта на window - хотя это только предположение.
Сами же пишите, что "window.eval() не меняет this с текущего объекта на window". Почему же аномалия с this, если window.eval чего-то там "не делает"?
Вообще, такого не должно происходить:
а) this приписывается,
б) потом меняется.
This - это нечто, вроде константы, значение которой определяется (до начала выполнения кода) значением объекта, в контексте которого вызван метод, или может зависеть от типа выполняемого кода. В данном случае выполняется особый тип - eval code. Если бы этот был стандартный процесс, т.е. выполнение глобальной функции eval, то проблем бы не возникло, т.к. все просто и понятно (ECMAScript Language Specification: 10.2.2 Eval Code). Но window.eval - это нестандартный вызов, и SpiderMonkey выполняет его своим, несколько непредсказуемым способом. Вот еще пример:
Code (JavaScript): скопировать код в буфер обмена
(function () {
    var x = true;
    window.eval('var y = typeof x == "boolean" && x;');
})();

alert(typeof y == 'boolean' && y); // -> true (with SpiderMonkey only)
 
Back to top
View user's profile Send private message Send e-mail
dimagolov
Участник форума



Joined: 04 Feb 2007
Posts: 1664
Карма: 96
   поощрить/наказать

Location: Christ Church, Barbados

PostPosted: Tue Jan 15, 2008 4:12 pm (спустя 5 часов 2 минуты; написано за 2 минуты 29 секунд)
   Post subject:
Reply with quote

AKS, спасибо за пример. Смотрю я на него и понять как он работает не могу. Совсем. Почему при вызове window.eval находиться x который внутри ф-ии объявлен, но при этом объявление var y происходит вне ф-ии? Какое логическое объяснение можно этому дать?

п.с. вообще хороший пример на тему eval is evil :)
Back to top
View user's profile Send private message
AKS
Участник форума



Joined: 28 Dec 2005
Posts: 1174
Карма: 102
   поощрить/наказать


PostPosted: Tue Jan 15, 2008 5:31 pm (спустя 1 час 18 минут; написано за 3 минуты 37 секунд)
   Post subject:
Reply with quote

dimagolov, я себе это представляю пока так, опираясь на алгоритм, описанный в 10.2.2 Eval Code (ECMAScript Language Specification). Там сказано, что из calling context (в данном примере – это контекст выполняющейся анонимной функции) берется все, что нужно для выполнения eval code (scope chain, variable object, this value). Но поскольку eval здесь вызван "от имени и по поручению" window, то в scrope chain, созданной для выполнения eval, SpiderMonkey ставит первым объектом этот самый window. При этом в scope chain, следом за window, также остаются и все остальные объекты из scope chain анонимной функции (в данном случае). Таким образом поиск любых идентификаторов будет начинаться с window (объявите переменную x еще и в глобальной области видимости, и тогда y будет присвоено значение глобальной переменной x, а не локальной). А если идентификатор не найден в window (это локальная переменная x), то поиск будет продолжен в variable object анонимной функции, который следует сразу за window в scrope chain. Вот так она и "обнаруживается".
Back to top
View user's profile Send private message Send e-mail
AKS
Участник форума



Joined: 28 Dec 2005
Posts: 1174
Карма: 102
   поощрить/наказать


PostPosted: Tue Jan 15, 2008 5:35 pm (спустя 3 минуты; написано за 1 минуту 38 секунд)
   Post subject:
Reply with quote

dimagolov wrote:
вообще хороший пример на тему eval is evil :)
Да, наверно лучше создать элемент script. Затем создать текстовый узел из строки с кодом, и разместить этот узел в script. А потом script разместить в документе.
Back to top
View user's profile Send private message Send e-mail
AKS
Участник форума



Joined: 28 Dec 2005
Posts: 1174
Карма: 102
   поощрить/наказать


PostPosted: Tue Jan 15, 2008 6:53 pm (спустя 1 час 17 минут; написано за 2 минуты 19 секунд)
   Post subject:
Reply with quote

Вот, придумал небольшой примерчик для иллюстрации того, какую scrope chain создает SpiderMonkey для выполнения window.eval:
Code (JavaScript): скопировать код в буфер обмена
eval('var x = "global";');

(function () {
    eval('var x = 1;');
    (function () {
        eval('var x = 2;');
        (function () {
            eval('var x = 3;');
            window.eval('var f = ' + f.toString());
        })();
    })();
})();

function f() {
    while (typeof x != 'undefined') {
        alert(x);
        delete x;
    };
};

f(); // -> 'global', 3, 2, 1
 
Все переменные, поочереди, начиная с window.x...
Back to top
View user's profile Send private message Send e-mail
An6rey
Участник форума



Joined: 30 Aug 2007
Posts: 69
Карма: 3
   поощрить/наказать


PostPosted: Tue Jan 15, 2008 8:35 pm (спустя 1 час 42 минуты; написано за 8 минут 30 секунд)
   Post subject:
Reply with quote

Отличный пример!
У меня теперь вопрос по deprecated object.eval().
Словл контекст в JavaScript употребляется в двух смыслах. В смысле глобальный/локальный и в смысле "контекст объекта" -
как в функции aply(). Так вот что значит object.eval() выполняется в конетексте object.
- this внутри object.eval() ссылается на object ???
- переменные var присоединяются к object ???
- вызов функций внури object.eval() происходят как вызов методов object.
В исключительном случае объекта window как раз глобальный контекст и контекст объекта не то чтобы совпадают, но имеют похожее поведения.
А как быть с произвольным object.eval() (хоть и deprecated)
Back to top
View user's profile Send private message
AKS
Участник форума



Joined: 28 Dec 2005
Posts: 1174
Карма: 102
   поощрить/наказать


PostPosted: Wed Jan 16, 2008 12:49 am (спустя 4 часа 13 минут; написано за 9 минут 34 секунды)
   Post subject:
Reply with quote

An6rey, я конечно попытаюсь ответить на вопросы, но мои ответы могут оказаться далеко от истины. Ответы на такие вопросы хорошо бы получить у разработчиков. ;)
An6rey wrote:
Словл контекст в JavaScript употребляется в двух смыслах. В смысле глобальный/локальный и в смысле "контекст объекта" -
как в функции aply(). Так вот что значит object.eval() выполняется в конетексте object.
Трудно сказать, правильно это или нет (я не задумывался пока, как это по-русски правильно сформулировать). Могу сказать, что относительно функций call/apply было бы, наверно, правильней выразиться иначе. Первый параметр для этих функций – это вызывающий объект (caller, вроде провайдера для значения this). Ключевое слово this в функции, вызванной этими методами, будет ссылаться на значение этого объекта.
А контекст – это абстракция. Вроде бы считается, что он (контекст) ассоциируется с теми или иными объектами. Вот, как раз, object.eval описывается, как анализ/вычисление строки кода в контексте object.
An6rey wrote:
this внутри object.eval() ссылается на object ???
А как узнать, куда и что ссылается в "нативных" методах. Ясно только одно – если this и ссылается на object, то этот this используется в качестве variable object. А тот this, который встречается в строке, которая передается параметром в eval – это уже другая ссылка, и ссылаться она должна на calling context. Это ярко демонстрирует SpiderMonkey, а вот Opera видимо заменяет целиком и полностью calling context на window, следовательно this при отсутствии calling context получает значение null, которое принудительно заменяется на значение global object.
An6rey wrote:
переменные var присоединяются к object ???
Вроде бы да (а куда им деваться ;) ):
Code (JavaScript): скопировать код в буфер обмена
var o = {
    f: function () {
        this.eval('const x = 1; function y () { return "o"; }');
    }
};

alert([o.x, o.y]);

o.f();

alert([o.x, o.y]);
An6rey wrote:
вызов функций внури object.eval() происходят как вызов методов object.
Ну так это же зависит от того, чьим методом будет функция в момент вызова:
Code (JavaScript): скопировать код в буфер обмена
var o = {
    f: function () {
        this.eval('y(); function y () { alert(this.f); }; ' + //
                  '(function () { alert(this.f); })();');   /*
    }
};

o.f();
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML